<html>
<head><meta charset="utf-8"><title>Deref Patterns,  stdlib type list · project-deref-patterns · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/index.html">project-deref-patterns</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html">Deref Patterns,  stdlib type list</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="229667642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229667642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229667642">(Mar 10 2021 at 14:22)</a>:</h4>
<p>I would like to start the discussion about supported stdlib types for deref patterns.<br>
This needs two lists, a list of requirements for stdlib types to satisfy, and a list of standard library types that do satisfy these requirements.</p>
<p>For the first list, in order to be sound, the deref implementation (and deref_mut) needs to be idempotent. Does it also need to be completely pure (IE., no calls to user-provided code whatsoever), or can we accept a single initial non-pure operation. If the former is the case, then this will disqualify <code>Lazy</code> and <code>SyncLazy</code> from deref patterns, as they are designed to call a user-provided function they first time they are dereferenced. Also, what exactly does idempotent mean, and what operations would reset it?</p>



<a name="229669095"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229669095" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229669095">(Mar 10 2021 at 14:30)</a>:</h4>
<p>For the second list, it may be reasonable to accept most of the types in the Standard Library that <code>Deref</code>s. The definate exception would be <code>Pin</code>, which can and should participate only if it's type parameter is a participating type. Other possible exceptions are <code>Lazy</code> and <code>SyncLazy</code> due to the fact that they may be initially impure, <code>Cow</code> and <code>AssertUnwindSafe</code>, since these can also be destructured (which is another interesting question), and <code>VaList</code>, which I would argue is useless for DerefPatterns, since you can't really structurally-match <code>VaListImpl</code>. <br>
For the record, the current exhaustive (I believe, please let me know if I'm missing any) list of potential candidates (from <a href="https://doc.rust-lang.org/nightly/std/ops/trait.Deref.html#implementors">https://doc.rust-lang.org/nightly/std/ops/trait.Deref.html#implementors</a>), can be categorized as follows:</p>
<ul>
<li>Language Reference Types:<code>&amp;T</code> and <code>&amp;mut T</code>.</li>
<li>Smart Pointer Types: <code>Box&lt;T&gt;</code>, <code>Arc&lt;T&gt;</code>, <code>Rc&lt;T&gt;</code></li>
<li>Growable Slice Collections: <code>Vec&lt;T&gt;</code>, <code>String</code>, <code>CString</code>, <code>OsString</code>, and <code>PathBuf</code></li>
<li>Smart Reference Guards: <code>Ref&lt;T&gt;</code>, <code>RefMut&lt;T&gt;</code>, <code>MutexGuard&lt;T&gt;</code>, <code>RwLockReadGuard&lt;T&gt;</code>, <code>RwLockWriteGuard&lt;T&gt;</code></li>
<li>Pin: <code>Pin&lt;P&gt;</code>, if <code>P</code> is a candidate.</li>
<li>Newtype Wrappers: <code>ManuallyDrop&lt;T&gt;</code>, <code>AssertUnwindSafe&lt;T&gt;</code> (but see note about <code>AssertUnwindSafe&lt;T&gt;</code>)</li>
<li>Lazy Initialization Wrapers: <code>Lazy&lt;T,F&gt;</code>, <code>SyncLazy&lt;T,F&gt;</code></li>
<li>Misc: <code>IOSlice</code>, <code>IOSliceMut</code>, <code>VaList</code>, <code>Cow&lt;B&gt;</code>, <code>PeekMut</code></li>
</ul>



<a name="229670051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229670051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229670051">(Mar 10 2021 at 14:34)</a>:</h4>
<p>In my opinion, the minimum I would want would be the Smart Pointer Types, <code>String</code>, and <code>Pin&lt;P&gt;</code> of such a type and of <code>&amp;T</code> and <code>&amp;mut T</code>. <br>
The language reference types can probably be excluded until support for user-defined types is being considered (since presumably they would fall under reference patterns), though if we use a different syntax for deref patterns, it could be reasonable to allow them (it would also keep implementation options open, and not require the implementation to special-special case <code>Pin&lt;&amp;T&gt;</code> or <code>Pin&lt;&amp;mut T&gt;</code> for these).</p>



<a name="229673236"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673236" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673236">(Mar 10 2021 at 14:51)</a>:</h4>
<p>I thought that <code>Lazy</code> and <code>SyncLazy</code> aren't eligible since they can panic, and not <code>Cow</code> since it can clone</p>



<a name="229673473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673473">(Mar 10 2021 at 14:53)</a>:</h4>
<p>Match arms can already panic in the if-guard</p>



<a name="229673579"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673579" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673579">(Mar 10 2021 at 14:53)</a>:</h4>
<p>I don't see what Cow being clonable has to do with it, it doesn't clone in the Deref impl</p>



<a name="229673618"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673618" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673618">(Mar 10 2021 at 14:53)</a>:</h4>
<p>if it's a user-defined clone function</p>



<a name="229673889"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673889" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673889">(Mar 10 2021 at 14:55)</a>:</h4>
<p>oh I see that Cow can qualify for deref patterns, provided a DerefMut impl is not added</p>



<a name="229673920"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229673920" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229673920">(Mar 10 2021 at 14:55)</a>:</h4>
<p><a href="https://hackmd.io/GBTt4ptjTh219SBhDCPO4A#Possible-solutions">https://hackmd.io/GBTt4ptjTh219SBhDCPO4A#Possible-solutions</a></p>



<a name="229687978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229687978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229687978">(Mar 10 2021 at 15:59)</a>:</h4>
<p><span class="user-mention silent" data-user-id="281739">oliver</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229673236">said</a>:</p>
<blockquote>
<p>I thought that <code>Lazy</code> and <code>SyncLazy</code> aren't eligible since they can panic, and not <code>Cow</code> since it can clone</p>
</blockquote>
<p>The potential issue with <code>Lazy</code> and <code>SyncLazy</code> is the fact they are impure the first time they are deferenced. </p>
<p>The issue with <code>Cow</code> is the fact it can also be destructured, and if we supported it, we'd have to decide how to deal with mixing both deref and structural matches.</p>



<a name="229688047"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229688047" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229688047">(Mar 10 2021 at 15:59)</a>:</h4>
<p>(The issue with <code>Cow</code> is also shared with <code>AssertUnwindSafe</code>)</p>



<a name="229708111"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229708111" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bstrie <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229708111">(Mar 10 2021 at 17:32)</a>:</h4>
<blockquote>
<p>The potential issue with Lazy and SyncLazy is the fact they are impure the first time they are deferenced.</p>
</blockquote>
<p>Is there a concrete example of how this could go wrong? The idempotency here seems pretty solid. Furthermore, assuming Lazy makes it into std, there would be no need to generalize this sort of "you can be impure once" exception to user-defined smart pointers, at least not at first. (I understand the desire to not let std "cheat" by doing things that user code can't do, but there's plenty of precedence (<code>TrustedFoo</code> traits), and furthermore Lazy seems like the only idempotent pointer of this kind that anybody would ever want to make?)</p>



<a name="229713105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229713105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229713105">(Mar 10 2021 at 18:01)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256342">bstrie</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229708111">said</a>:</p>
<blockquote>
<blockquote>
<p>The potential issue with Lazy and SyncLazy is the fact they are impure the first time they are deferenced.</p>
</blockquote>
<p>Is there a concrete example of how this could go wrong? The idempotency here seems pretty solid. Furthermore, assuming Lazy makes it into std, there would be no need to generalize this sort of "you can be impure once" exception to user-defined smart pointers, at least not at first. (I understand the desire to not let std "cheat" by doing things that user code can't do, but there's plenty of precedence (<code>TrustedFoo</code> traits), and furthermore Lazy seems like the only idempotent pointer of this kind that anybody would ever want to make?)</p>
</blockquote>
<p>One of the reasons that only stdlib types are being persued is because lang-team doesn't necessarily want to introduce impure operations in pattern matching, yet &lt;<a href="https://github.com/rust-lang/lang-team/pull/78#issuecomment-780631891">https://github.com/rust-lang/lang-team/pull/78#issuecomment-780631891</a>&gt;.<br>
Perhaps it is reasonable to special case <code>Lazy</code> and <code>SyncLazy</code>, but it also may not be; if we want an answer to that, we'd need to ask T-lang, probably at a design meeting in the future.</p>



<a name="229730032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229730032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229730032">(Mar 10 2021 at 19:44)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> I was in the meeting that summary came from. I think for both that meeting and that summary, we weren't thinking about types like <code>Lazy</code>, so we were equating "not pure" with "potentially not idempotent". A type like <code>Lazy</code> that runs user code <em>once</em> but then never again, and provides idempotence atop that, seems potentially reasonable.</p>



<a name="229730182"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229730182" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229730182">(Mar 10 2021 at 19:45)</a>:</h4>
<p>It's possible that some members of the team may object to code running at pattern-match time for other reasons, but I'm not aware of those reasons.</p>



<a name="229740780"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229740780" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229740780">(Mar 10 2021 at 20:44)</a>:</h4>
<p>Yeah, it's possible that "stable" would be a better word than "pure", like how it's used in <a href="http://kimundi.github.io/owning-ref-rs/owning_ref/trait.CloneStableAddress.html">http://kimundi.github.io/owning-ref-rs/owning_ref/trait.CloneStableAddress.html</a></p>



<a name="229740865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229740865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229740865">(Mar 10 2021 at 20:45)</a>:</h4>
<p>The one thing that comes to mind for purity is if idempotency is still observable</p>



<a name="229741101"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229741101" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229741101">(Mar 10 2021 at 20:46)</a>:</h4>
<p>Like whether <code>{ A(x) if foo(x) =&gt; ..., A(deref x) =&gt; ... }</code> is allowed to potentially call deref even if the foo predicate is true.</p>



<a name="229741196"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229741196" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229741196">(Mar 10 2021 at 20:47)</a>:</h4>
<p>(But I haven't thought through whether that'd be concerning, nor whether it'd be an implementation concern.)</p>



<a name="229744982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229744982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229744982">(Mar 10 2021 at 21:08)</a>:</h4>
<p>I thought match arms were guaranteed to be tried in order? Since the difference is observable due to if-guards?</p>



<a name="229760217"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229760217" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229760217">(Mar 10 2021 at 22:38)</a>:</h4>
<p>Only the <code>if</code> bits need to be in order, though -- it could load all the discriminants and such eagerly today, then do the guard predicates.</p>
<p>(I don't know if the implementation actually takes advantage of that flexibility, though)</p>



<a name="229760270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229760270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229760270">(Mar 10 2021 at 22:39)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229730032">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> I was in the meeting that summary came from. I think for both that meeting and that summary, we weren't thinking about types like <code>Lazy</code>, so we were equating "not pure" with "potentially not idempotent". A type like <code>Lazy</code> that runs user code <em>once</em> but then never again, and provides idempotence atop that, seems potentially reasonable.</p>
</blockquote>
<p>Makes sense. So then it wouldn't have an issue from a T-lang perspective? <br>
I still wouldn't necessarily put it on the "No issues at all" list, because even being initially impure could cause issues, and limit certain optimizations.</p>



<a name="229761492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229761492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229761492">(Mar 10 2021 at 22:49)</a>:</h4>
<p><span class="user-mention silent" data-user-id="125270">scottmcm</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229760217">said</a>:</p>
<blockquote>
<p>Only the <code>if</code> bits need to be in order, though -- it could load all the discriminants and such eagerly today, then do the guard predicates.</p>
<p>(I don't know if the implementation actually takes advantage of that flexibility, though)</p>
</blockquote>
<p>It could. Another optimization that's been comtemplated was reducing the number of deref calls (in theory, you could reduce it to merely 0 or 1 deref calls, and some number of deref_mut calls).</p>



<a name="229794959"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229794959" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229794959">(Mar 11 2021 at 05:07)</a>:</h4>
<p><span class="user-mention" data-user-id="257758">@Connor Horman</span> We'd appreciate an assessment of potential practical issues; I'm just suggesting that we're not against it on principle.</p>



<a name="229840018"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/229840018" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#229840018">(Mar 11 2021 at 12:27)</a>:</h4>
<p>I would also add that I think it would be completely reasonable to pick 1-2 "easy" types, document the restrictions required for the initial design (and ideally how they're compatible with extensions, but this mostly is just to make sure we're not boxing ourselves in unintentionally) - I don't think the initial rfc needs to specify an exhaustive list, though having a set of criteria that can be applied to an arbitrary type may be useful.</p>
<p>For example, I might exclude those types that have user defined code completely for now, and just restrict ourselves to Arc/Rc/Box/String, for example, which all feel much simpler to design a system for over, for example, Lazy.</p>



<a name="230036511"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230036511" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230036511">(Mar 12 2021 at 14:23)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229794959">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> We'd appreciate an assessment of potential practical issues; I'm just suggesting that we're not against it on principle.</p>
</blockquote>
<p>Indeed. And if the project does end up considering it's viability, presumably we'd have an assesment to present, regardless of whether or not it is proposed to be included or not.</p>
<p><span class="user-mention silent" data-user-id="116122">simulacrum</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/229840018">said</a>:</p>
<blockquote>
<p>I would also add that I think it would be completely reasonable to pick 1-2 "easy" types, document the restrictions required for the initial design (and ideally how they're compatible with extensions, but this mostly is just to make sure we're not boxing ourselves in unintentionally) - I don't think the initial rfc needs to specify an exhaustive list, though having a set of criteria that can be applied to an arbitrary type may be useful.</p>
<p>For example, I might exclude those types that have user defined code completely for now, and just restrict ourselves to Arc/Rc/Box/String, for example, which all feel much simpler to design a system for over, for example, Lazy.</p>
</blockquote>
<p>That is an option, and a potentially reasonable one. And even if we don't necessarily limit it to that extent, the project could potentially even avoid consideration of <code>Lazy</code> at this time on the basis of it being unstable (dependant on any known timelines for it's stablization).</p>



<a name="230036940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230036940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230036940">(Mar 12 2021 at 14:26)</a>:</h4>
<p>In any case, it may be a good idea to decide whether we want to set the types first, then work out the requirements; set the requirements, then work out viable types; or some combination (such as deciding on a set of "must support" types, working out requirements that don't exclude those, then deciding the rest of the types).</p>



<a name="230045086"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230045086" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230045086">(Mar 12 2021 at 15:15)</a>:</h4>
<p>For the unstable version, why not just support the widest conveniently-supportable set of types? For example everything with a deref impl. This whitelist approach makes sense for the stable version but for unstable it seems like having the feature implemented so people can play with it is more important than restricting it where we aren't sure about what we want the semantics to be</p>



<a name="230045541"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230045541" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230045541">(Mar 12 2021 at 15:17)</a>:</h4>
<p>(If on the other hand for some reason it's easier to support a small list of types rather than all types satisfying some trait or set of constraints, then a whitelist would make sense since it's just an MVP anyway)</p>



<a name="230073476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230073476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230073476">(Mar 12 2021 at 18:07)</a>:</h4>
<p>If you are referring to all types with a deref impl in the standard library, that might be a good way forward. Evaluate the requirements in the wild rather than through theoretical analysis.<br>
If you are referring to all types period, then T-lang has expressed that they do <em>not</em> want to persue that at this time with this project (see relevant discussion on the charter pr, &lt;<a href="https://github.com/rust-lang/lang-team/pull/78">https://github.com/rust-lang/lang-team/pull/78</a>&gt;). <br>
One of the primary issues is that, if deref patterns are treated as exhaustive, then an impure deref impl can be unsound, as you can write a safe implementation of <code>Deref</code> that returns a different value each time, and that misses the match arms.</p>



<a name="230074217"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230074217" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230074217">(Mar 12 2021 at 18:12)</a>:</h4>
<p>Well I doubt such a thing would be accepted by the compiler anyway, because it has to be desugared somehow</p>



<a name="230075683"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230075683" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230075683">(Mar 12 2021 at 18:24)</a>:</h4>
<p>At the implementation level, it is now a question of whether the desugaring attempts to deduplicate deref calls or not.</p>
<ol>
<li>If we do deduplicate deref calls, then it has a chance to support exhaustive matching without any regard for idempotence of deref, although that might make it easier to explain to folks for the stable version.</li>
<li>If not, then there is the question of what to do with the leftover matches; if you use an <code>unreachable_unchecked</code> there then yes that is a soundness concern, for user types but also for things like <code>Arc</code>, where we are now relying on a very particular property about the deref call and its interaction with other code that is not represented in any <code>unsafe</code> block.</li>
<li>If you use a <code>panic!("match failed")</code>, then it should be memory safe, and this is probably the easiest thing to implement, although people will definitely want control over what happens in this branch eventually.</li>
</ol>



<a name="230076855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230076855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230076855">(Mar 12 2021 at 18:33)</a>:</h4>
<p>From <a href="https://github.com/rust-lang/lang-team/pull/78#issuecomment-780631891">https://github.com/rust-lang/lang-team/pull/78#issuecomment-780631891</a> it looks like the idea is to do (2), with the soundness issue being resolved by the whitelist, or possibly <code>DerefPure</code>. Although it looks like <code>DerefPure</code> is being deferred, I think that it makes the design of <code>DerefPure</code> somewhat easy: <code>DerefPure</code> is an unsafe marker trait whose safety condition is "everything needed for the implementation of (2) to be sound", which boils down to some kind of idempotence.</p>



<a name="230237550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230237550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230237550">(Mar 14 2021 at 13:11)</a>:</h4>
<p>Wrt. (1), that is something I'd like to enable, but not necessarily required for exhaustiveness as it's impossible to totally deduplicate it, see this code</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="n">x</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">is_none</span><span class="p">()</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>That requires 2 deref calls, (three if you count the if guard).</p>
<p>I'd also argue that deref patterns aren't really syntax sugar over an existing construct; they could be closely approximated with, but not actually desugared to, if let guards. <br>
Otherwise, you are right, DerefPure would need to restrict implementors to what makes (2) sound, and possibly more to allow the freedom to deduplicate deref calls. However, as this project is not pursuing  DerefPure, this is somewhat moot (though partially relevant to constructing a set of rules for stdlib types.</p>



<a name="230418133"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230418133" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dirkjan Ochtman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230418133">(Mar 15 2021 at 21:04)</a>:</h4>
<blockquote>
<p>In my opinion, the minimum I would want would be the Smart Pointer Types, String, and Pin&lt;P&gt; of such a type and of &amp;T and &amp;mut T.</p>
</blockquote>
<p>IMO <code>Vec&lt;T&gt;</code> to <code>[T]</code> is also one of the very important ones.</p>



<a name="230419515"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230419515" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230419515">(Mar 15 2021 at 21:13)</a>:</h4>
<p>Ah, right, slice patterns work, don't they?</p>



<a name="230503503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230503503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230503503">(Mar 16 2021 at 12:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/230237550">said</a>:</p>
<blockquote>
<p>Wrt. (1), that is something I'd like to enable, but not necessarily required for exhaustiveness as it's impossible to totally deduplicate it, see this code</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="n">x</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">is_none</span><span class="p">()</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>That requires 2 deref calls, (three if you count the if guard).</p>
<p>I'd also argue that deref patterns aren't really syntax sugar over an existing construct; they could be closely approximated with, but not actually desugared to, if let guards. <br>
Otherwise, you are right, DerefPure would need to restrict implementors to what makes (2) sound, and possibly more to allow the freedom to deduplicate deref calls. However, as this project is not pursuing  DerefPure, this is somewhat moot (though partially relevant to constructing a set of rules for stdlib types.</p>
</blockquote>
<p>Why would this need more than one deref_mut call?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="p">.</span><span class="n">deref_mut</span><span class="p">();</span><span class="w"></span>
<span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">is_none</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="o">&amp;</span><span class="nb">Some</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">v</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
</code></pre></div>



<a name="230504349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230504349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230504349">(Mar 16 2021 at 12:38)</a>:</h4>
<p>This confused me in the tracking document too </p>
<blockquote>
<p>this case could be implemented as a single deref_mut, then reborrowing. However, this would not work in a case like this:</p>
<p><div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">0</span><span class="o">..</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (1)</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">4</span><span class="o">..</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (2)</span>
<span class="w">    </span><span class="n">v</span><span class="o">@&amp;</span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (3)</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">8</span><span class="o">..</span><span class="mi">11</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (4)</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div><br>
</p>
</blockquote>
<p>Why wouldn't this just be </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">deref_mut</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">0</span><span class="o">..=</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">4</span><span class="o">..=</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">8</span><span class="o">..=</span><span class="mi">11</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// the original code wasn't exhaustive</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="230504874"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230504874" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230504874">(Mar 16 2021 at 12:42)</a>:</h4>
<p>It seems to me like deref deduplication is easily the best option as long as its viable, so I'm probably missing something important...</p>



<a name="230509143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230509143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230509143">(Mar 16 2021 at 13:13)</a>:</h4>
<p>This playground demonstrates how I'd expect the examples I've seen so far to work: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2f5218def15c680a87d5513121befaf7">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=2f5218def15c680a87d5513121befaf7</a></p>
<p>They're all simple desugarings to existing Rust code that's already exhaustive</p>



<a name="230512238"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230512238" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230512238">(Mar 16 2021 at 13:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="263805">Plecra</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list/near/230504349">said</a>:</p>
<blockquote>
<p>This confused me in the tracking document too </p>
<blockquote>
<p>this case could be implemented as a single deref_mut, then reborrowing. However, this would not work in a case like this:</p>
<p><div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">0</span><span class="o">..</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (1)</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">4</span><span class="o">..</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (2)</span>
<span class="w">    </span><span class="n">v</span><span class="o">@&amp;</span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (3)</span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">deref</span><span class="w"> </span><span class="n">v</span><span class="o">@</span><span class="mi">8</span><span class="o">..</span><span class="mi">11</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="o">..</span><span class="p">.,</span><span class="w"> </span><span class="c1">// (4)</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div><br>
</p>
</blockquote>
<p>Why wouldn't this just be </p>
<p><div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">deref_mut</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">0</span><span class="o">..=</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">4</span><span class="o">..=</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">8</span><span class="o">..=</span><span class="mi">11</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{},</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// the original code wasn't exhaustive</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div><br>
</p>
</blockquote>
<p>The deref type is inside the <code>Option</code> (this can be shown easily by the fact that the <code>deref</code> is indicated inside of <code>Some</code>). <br>
The reason why the <code>deref_mut</code> can't be preemptively used and kept arround for the remaining match arms, is because <code>v@None</code> requires matching the option, thus borrowing it. <br>
This has a number of issues, but primarily, if <code>deref_mut</code> returns an interior pointer (such as the implementation for <code>ManuallyDrop</code> or <code>AssertUnwindSafe</code>), according to Stacked Borrows, the Shared borrow of the Option would invalidate the mutable borrow of that interior pointer (and any pointers derived therefrom). While Stacked Borrows is not normative at this time, my preference would be that Deref Patterns not undermine it. Your desguaring would be correct if the <code>Option</code> was inside the Deref Type (IE. <code>Box&lt;Option&gt;</code> rather than <code>Option&lt;Box&gt;</code>).</p>



<a name="230512827"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230512827" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230512827">(Mar 16 2021 at 13:38)</a>:</h4>
<p>Haha, yea I did stumble a bit with grokking that example - the example I gave in the playground with the types the right way around looked like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">core</span>::<span class="n">mem</span>::<span class="n">ManuallyDrop</span>::<span class="n">new</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">ptr</span><span class="p">.</span><span class="n">deref_mut</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="o">..=</span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">v</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="p">(</span><span class="mi">4</span><span class="o">..=</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">        </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="p">(</span><span class="mi">8</span><span class="o">..=</span><span class="mi">11</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">v</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">},</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">v</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="230512841"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230512841" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230512841">(Mar 16 2021 at 13:38)</a>:</h4>
<p>(which again, compiles now)</p>



<a name="230512924"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230512924" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230512924">(Mar 16 2021 at 13:39)</a>:</h4>
<p>And this does logically reorder the match, which I've been thinking through the consequences of</p>



<a name="230512931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230512931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230512931">(Mar 16 2021 at 13:39)</a>:</h4>
<p>The issue is that you've now changed the order of the match arms (which matters if the arm has an if guard).</p>



<a name="230513061"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230513061" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230513061">(Mar 16 2021 at 13:40)</a>:</h4>
<p>Would you mind giving an example of when it would change the behaviour of a guard?</p>



<a name="230513099"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230513099" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230513099">(Mar 16 2021 at 13:40)</a>:</h4>
<p>I've been trying to come up with one and my minds blank :P</p>



<a name="230513220"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230513220" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230513220">(Mar 16 2021 at 13:41)</a>:</h4>
<p>afaict, the branches that this would "reorder" would be unreachable anyway</p>



<a name="230513772"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230513772" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230513772">(Mar 16 2021 at 13:44)</a>:</h4>
<p><code>if</code> guards can have side effects. This particular example wouldn't work, but it's trivial to come up with a case for something like Cow, which can both the dereferenced and destructured.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">check_and_print</span><span class="p">(</span><span class="n">x</span>: <span class="kt">i32</span><span class="p">,</span><span class="n">y</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">y</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Cow</span>::<span class="n">Owned</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span><span class="w"></span>
<span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">c</span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="n">deref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="mi">5</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{} in [0,5)"</span><span class="p">,</span><span class="n">x</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">Cow</span>::<span class="n">Owned</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">check_and_print</span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Owned {}&lt;5"</span><span class="p">,</span><span class="n">x</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">deref</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">check_and_print</span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">,</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{} in [5,10)"</span><span class="p">,</span><span class="n">x</span><span class="p">),</span><span class="w"></span>
<span class="w">    </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Something else"</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="230514050"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230514050" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230514050">(Mar 16 2021 at 13:46)</a>:</h4>
<p>You can't reorder any of those patterns without potentially changing either the side effects in the if guards, or the outcome of the match.</p>



<a name="230514464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230514464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230514464">(Mar 16 2021 at 13:49)</a>:</h4>
<p>(Though actually, you can't <code>deref_mut</code> <code>Cow</code>, but the same argument applies in inverse, since the <code>Cow::Owned</code> pattern mutably borrows <code>x</code> and thus reborrows the entire <code>Cow</code> as mutable, potentially invalidating the <code>deref</code> calls).</p>



<a name="230515300"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230515300" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230515300">(Mar 16 2021 at 13:54)</a>:</h4>
<p>So does that mean this only applies to enums that we want to destructure and deref in the same match?</p>



<a name="230515699"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230515699" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230515699">(Mar 16 2021 at 13:57)</a>:</h4>
<p>hm.. no I don't think so</p>



<a name="230515762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230515762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230515762">(Mar 16 2021 at 13:57)</a>:</h4>
<p>this affects all simpler situations where you want to call a method on the pointer type too</p>



<a name="230515825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230515825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230515825">(Mar 16 2021 at 13:58)</a>:</h4>
<p>Thanks :) That really helps</p>



<a name="230515929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230515929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230515929">(Mar 16 2021 at 13:58)</a>:</h4>
<p>Indeed, as well as cases where you could dereference two embedded things. <code>Result&lt;impl Deref,impl Deref&gt;</code> comes to mind.</p>



<a name="230516302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230516302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230516302">(Mar 16 2021 at 14:01)</a>:</h4>
<p>I wonder if it'd be worth permitting cases where rustc can implement it with a single <code>deref_mut</code> so as to make the common AST matching cases simple</p>



<a name="230516440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230516440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230516440">(Mar 16 2021 at 14:02)</a>:</h4>
<p>It'd also be great to have a "realistic" example of when this limitation with multiple dereferences would actually apply for the motivation section of the RFC</p>



<a name="230517704"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230517704" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230517704">(Mar 16 2021 at 14:08)</a>:</h4>
<p>That seems incredibly limiting, though I can't come up with any specific examples that would be used in the real world.</p>
<p>In any case, the "single <code>deref_mut</code>" restriction shouldn't even be necessary, as (with the exception of <code>Lazy</code> and <code>SyncLazy</code>, which are idempotent), all of the types under consideration for this project are known to have only completely pure (no side effects) deref and deref_mut implementations, so the compiler can insert and remove as many as it wants without changing the behaviour (and while maintaining the exhaustiveness rule).</p>



<a name="230518105"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230518105" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230518105">(Mar 16 2021 at 14:11)</a>:</h4>
<p>for sure! and I do think it falls under future considerations, but it'd be nice to leave the door open to a safe API for user-defined derefs</p>



<a name="230518149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230518149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230518149">(Mar 16 2021 at 14:11)</a>:</h4>
<p>and this seems like a pretty widely-useful subset that could be used safely</p>



<a name="230518374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230518374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230518374">(Mar 16 2021 at 14:12)</a>:</h4>
<p>Indeed, and that may be an additional route to persue for user-defined derefs (though by "single <code>deref_mut</code> call" I assume you are also including cases that can be implemented using a single <code>deref</code> call), though this project is not doing so, as mentioned.</p>



<a name="230518426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/230518426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Plecra <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#230518426">(Mar 16 2021 at 14:13)</a>:</h4>
<p>^^ thanks for your time</p>



<a name="231109112"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/Deref%20Patterns%2C%20%20stdlib%20type%20list/near/231109112" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/Deref.20Patterns.2C.20.20stdlib.20type.20list.html#231109112">(Mar 20 2021 at 00:43)</a>:</h4>
<p>Alright, so we should consider a plan.<br>
I think that we should start with a reduced set, probably, <code>Box</code>, <code>Rc, </code>Arc<code>, </code>String<code>, </code>Vec<code>, and </code>Pin`s of them, and then implement that behind a feature gate (once we have syntax resolved, or at least a decent idea of how we'd do the syntax). <br>
Does this seem like a reasonable plan for now?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>